package joinpay

import (
	"bytes"
	"encoding/json"
	"hotgo/utility/joinpay/utils"
	"strconv"
	"strings"
)

const SinglePayApi = "https://www.joinpay.com/payment/pay/singlePay"

type SinglePayReq struct {
	UserNo                string `json:"userNo"`                // 商户编号
	ProductCode           string `json:"productCode"`           // 产品类型
	RequestTime           string `json:"requestTime"`           // 交易请求时间
	MerchantOrderNo       string `json:"merchantOrderNo"`       // 商户订单号
	ReceiverAccountNoEnc  string `json:"receiverAccountNoEnc"`  // 收款人银行卡卡号
	ReceiverNameEnc       string `json:"receiverNameEnc"`       // 收款人银行卡持卡人名称
	ReceiverAccountType   string `json:"receiverAccountType"`   // 账户类型：201 对私账户
	ReceiverBankChannelNo string `json:"receiverBankChannelNo"` // 收款账户联行号 （对公账户必须填写此字段）
	PaidAmount            string `json:"paidAmount"`            // 交易金额(代付金额:单位:元，精确到分，保留两位小数。例如:10.23)
	Currency              string `json:"currency"`              // 币种：201 人民币
	IsChecked             string `json:"isChecked"`             // 是否复核（复核:201【需到汇聚商户后台审核通过才会打款】，不复核:202）
	PaidDesc              string `json:"paidDesc"`              // 代付说明(长度 为 30 个字符以内)
	PaidUse               string `json:"paidUse"`               // 代付用途
	CallbackUrl           string `json:"callbackUrl"`           // 代付完成后异步回调通知地址
	Hmac                  string `json:"hmac"`                  // 签名数据
}

type SinglePayResp struct {
	StatusCode int    `json:"statusCode"`
	Message    string `json:"message"`
	Data       struct {
		ErrorCode       string `json:"errorCode"`
		ErrorDesc       string `json:"errorDesc"`
		UserNo          string `json:"userNo"`
		MerchantOrderNo string `json:"merchantOrderNo"`
		Hmac            string `json:"hmac"`
	} `json:"data"`
}

func SinglePay(merchantKey string, req SinglePayReq) (*SinglePayResp, error) {
	var reqData bytes.Buffer
	reqData.WriteString(req.UserNo)
	reqData.WriteString(req.ProductCode)
	reqData.WriteString(req.RequestTime)
	reqData.WriteString(req.MerchantOrderNo)
	reqData.WriteString(req.ReceiverAccountNoEnc)
	reqData.WriteString(req.ReceiverNameEnc)
	reqData.WriteString(req.ReceiverAccountType)
	reqData.WriteString(req.ReceiverBankChannelNo)
	reqData.WriteString(req.PaidAmount)
	reqData.WriteString(req.Currency)
	reqData.WriteString(req.IsChecked)
	reqData.WriteString(req.PaidDesc)
	reqData.WriteString(req.PaidUse)
	reqData.WriteString(req.CallbackUrl)

	signByMD5 := utils.SignByMD5(reqData.String(), merchantKey)
	req.Hmac = signByMD5
	marshal, err := json.Marshal(req)
	if err != nil {
		return nil, err
	}
	body, err := utils.PostRequest(SinglePayApi, marshal)
	if err != nil {
		return nil, err
	}
	var resp *SinglePayResp
	err = json.Unmarshal(body, &resp)

	var respData bytes.Buffer
	respData.WriteString(strconv.Itoa(resp.StatusCode))
	respData.WriteString(resp.Message)
	respData.WriteString(resp.Data.ErrorCode)
	respData.WriteString(resp.Data.ErrorDesc)
	respData.WriteString(resp.Data.UserNo)
	respData.WriteString(resp.Data.MerchantOrderNo)
	signResp := utils.SignByMD5(respData.String(), merchantKey)
	//logx.Infof("响应结果拼接 --------------------------------->%s", respData.String())
	//logx.Infof("响应结果拼接签名 --------------------------------->%s", signResp)
	//logx.Infof("响应结果拼接签名 --------------------------------->%s", resp.Data.Hmac)
	if signResp != strings.ToUpper(resp.Data.Hmac) {
		//logx.Info("响应结果验签 --------------------------------->不符合")
		return resp, err
	}
	//logx.Info("响应结果验签 --------------------------------->符合")

	return resp, err
}
